package io.github.lee.core.ui

import android.view.View
import android.widget.FrameLayout
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.LayoutManager
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.chad.library.adapter4.BaseQuickAdapter
import com.chad.library.adapter4.QuickAdapterHelper
import com.chad.library.adapter4.loadState.LoadState
import com.chad.library.adapter4.loadState.leading.LeadingLoadStateAdapter
import com.chad.library.adapter4.loadState.trailing.TrailingLoadStateAdapter
import com.fondesa.recyclerviewdivider.BaseDividerItemDecoration
import io.github.lee.core.ui.databinding.UiLayoutRefreshBinding
import io.github.lee.core.vm.BaseRefreshViewModel
import io.github.lee.core.vm.err.ViewModelException

open class BaseRefreshFragment<VM : BaseRefreshViewModel<*>> :
    BaseFragment<UiLayoutRefreshBinding, VM>() {
    protected var mAdapterHelper: QuickAdapterHelper? = null
        private set

    protected open var enableRefresh = true

    //        set(value) {
//            field = value
//            if (!value) {
//                vb?.refreshLayout?.isRefreshing = false
//            }
//        }
    protected open var enableLoadMore = true

    protected open var autoRefresh = true

    protected val recyclerView: RecyclerView?
        get() = vb?.recyclerView
    protected val refreshLayout: SwipeRefreshLayout?
        get() = vb?.refreshLayout

    //===Desc:======================================================================================
    override fun onCreateSuccess(): UiLayoutRefreshBinding =
        UiLayoutRefreshBinding.inflate(layoutInflater)

    //===Desc:======================================================================================

    override fun onObserved() {
        super.onObserved()
        vm?.collectCheckFullPage {
            if (it) {
                mAdapterHelper?.trailingLoadStateAdapter?.checkDisableLoadMoreIfNotFullPage()
            }
        }
    }

    override fun onSetViewListener() {
        super.onSetViewListener()
        vb?.refreshLayout?.setOnRefreshListener {
            vm?.onRefreshOrLoadMore(true)
        }
    }

    override fun onSetViewData() {
        super.onSetViewData()
        vm?.apply {
            val builder = QuickAdapterHelper.Builder(adapter)

            val trailingLoadAdapter = onCreateTrailingLoadAdapter()
            val listener = object :
                TrailingLoadStateAdapter.OnTrailingListener {
                override fun onFailRetry() {
                    onRefreshOrLoadMore(false)
                }

                override fun onLoad() {
                    onRefreshOrLoadMore(false)
                }

                override fun isAllowLoading(): Boolean {
                    return if (enableLoadMore) {
                        vb?.refreshLayout?.isRefreshing != true
                    } else {
                        false
                    }
                }
            }
            if (null == trailingLoadAdapter) {
                builder.setTrailingLoadStateAdapter(listener)
            } else {
                trailingLoadAdapter.setOnLoadMoreListener(listener)
                builder.setTrailingLoadStateAdapter(trailingLoadAdapter)
            }

            val config = onCreateAdapterConfig()
            if (null != config) {
                builder.setConfig(config)
            }

            mAdapterHelper = builder.build()
        }

        vb?.recyclerView?.apply {
            layoutManager = onCreateLayoutManager() ?: LinearLayoutManager(mContext)
            adapter = mAdapterHelper?.adapter
        }

        try {
            vm?.adapter?.isStateViewEnable = true
        } catch (e: Exception) {
            e.printStackTrace()
        }

        showSuccess()
        vb?.refreshLayout?.isEnabled = enableRefresh
        if (autoRefresh) {
            if (enableRefresh) {
                vb?.refreshLayout?.post {
                    vb?.refreshLayout?.isRefreshing = true
                    vm?.onRefreshOrLoadMore(true)
                }
            } else {
                vm?.onRefreshOrLoadMore(true)
            }
        }
        if (!enableLoadMore) {
            mAdapterHelper?.leadingLoadStateAdapter?.loadState =
                LoadState.None
            mAdapterHelper?.trailingLoadStateAdapter?.loadState =
                LoadState.None
        }
    }

    //===Desc:======================================================================================
    protected fun setupRefreshLayout(block: (refreshLayout: SwipeRefreshLayout) -> Unit) {
        val layout = vb?.refreshLayout
        if (null != layout) {
            block(layout)
        }
    }

    protected open fun onCreateTrailingLoadAdapter(): TrailingLoadStateAdapter<*>? =
        null

    protected open fun onCreateLeadingLoadListener(): LeadingLoadStateAdapter.OnLeadingListener? =
        null

    protected open fun onCreateAdapterConfig(): ConcatAdapter.Config? = null

    protected open fun onCreateLayoutManager(): LayoutManager? = null

    //===Desc:======================================================================================

    override fun showLoading(tip: String?) {
        // super.showLoading(tip)
        showSuccess()
        vb?.refreshLayout?.isRefreshing = true
    }

    override fun showEmpty(e: ViewModelException?) {
        showSuccess()

        refreshFail(e)
        loadMoreFail(e)
        emptyVb = onCreateEmpty()?.also {
            it.lifecycleOwner = this@BaseRefreshFragment
            it.root.layoutParams = RecyclerView.LayoutParams(
                RecyclerView.LayoutParams.MATCH_PARENT,
                RecyclerView.LayoutParams.MATCH_PARENT
            )
        }
        vm?.adapter?.isStateViewEnable = true
        vm?.adapter?.stateView = emptyVb?.root
        vb?.refreshLayout?.isRefreshing = false
    }

    override fun showError(e: ViewModelException?) {
        //super.showError(e)
        showSuccess()
        refreshFail(e)
        loadMoreFail(e)

        errorVb = onCreateError()?.also {
            it.lifecycleOwner = this@BaseRefreshFragment
            it.root.layoutParams = RecyclerView.LayoutParams(
                RecyclerView.LayoutParams.MATCH_PARENT,
                RecyclerView.LayoutParams.MATCH_PARENT
            )
        }

        vm?.adapter?.isStateViewEnable = true
        vm?.adapter?.stateView = emptyVb?.root
        vb?.refreshLayout?.isRefreshing = false

        vm?.adapter?.isStateViewEnable = true
        vm?.adapter?.stateView = errorVb?.root
        vb?.refreshLayout?.isRefreshing = false
    }

    override fun refreshSuccess(hasMore: Boolean?) {
        super.refreshSuccess(hasMore)
        vb?.refreshLayout?.isRefreshing = false
        //重置“加载更多”时状态
        if (enableLoadMore) {
            mAdapterHelper?.trailingLoadStateAdapter?.loadState =
                LoadState.NotLoading(!(hasMore ?: true))
            mAdapterHelper?.leadingLoadStateAdapter?.loadState =
                LoadState.NotLoading(!(hasMore ?: true))
        }
    }

    override fun refreshFail(e: ViewModelException?) {
        super.refreshFail(e)
        vb?.refreshLayout?.isRefreshing = false
    }

    override fun loadMoreSuccess(hasMore: Boolean?) {
        super.loadMoreSuccess(hasMore)
        mAdapterHelper?.leadingLoadStateAdapter?.loadState =
            LoadState.NotLoading(!(hasMore ?: true))
        mAdapterHelper?.trailingLoadStateAdapter?.loadState =
            LoadState.NotLoading(!(hasMore ?: true))
    }

    override fun loadMoreFail(e: ViewModelException?) {
        super.loadMoreFail(e)
        mAdapterHelper?.leadingLoadStateAdapter?.loadState = if (null == e) {
            LoadState.None
        } else {
            LoadState.Error(e)
        }
    }

    //===Desc:======================================================================================
    protected fun removeAdapter(adapter: BaseQuickAdapter<*, *>) {
        mAdapterHelper?.removeAdapter(adapter)
    }

    protected fun addHeaderAdapter(adapter: BaseQuickAdapter<*, *>, index: Int? = null) {
        if (null == index) {
            mAdapterHelper?.addBeforeAdapter(adapter)
        } else {
            mAdapterHelper?.addBeforeAdapter(index, adapter)
        }
    }

    protected fun addFooterAdapter(adapter: BaseQuickAdapter<*, *>, index: Int? = null) {
        if (null == index) {
            mAdapterHelper?.addAfterAdapter(adapter)
        } else {
            mAdapterHelper?.addAfterAdapter(index, adapter)
        }
    }


    //===Desc:======================================================================================

    protected fun addPageHoverView(view: View) {
        val params = view.layoutParams
        if (params !is FrameLayout.LayoutParams) {
            throw IllegalArgumentException("Create the FrameLayout.LayoutParams parameter")
        }
        contentFrameLayout.addView(view, params)
    }

    protected fun addPageHoverView(view: View, params: FrameLayout.LayoutParams) {
        contentFrameLayout.addView(view, params)
    }


    protected fun addItemDecoration(vararg decorations: BaseDividerItemDecoration) {
        decorations.forEach {
            if (null != recyclerView) {
                it.addTo(recyclerView!!)
            }
        }
    }
}